home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 3
/
Cream of the Crop 3.iso
/
comm
/
wnos5src.zip
/
AX25DUMP.C
< prev
next >
Wrap
Text File
|
1993-08-09
|
5KB
|
219 lines
/* DAMA enhancements by DL1BKE, 920531 */
#include <stdio.h>
#include "global.h"
#include "config.h"
#ifdef AX25
#include "mbuf.h"
#include "ax25.h"
#include "timer.h"
#include "trace.h"
#include "socket.h"
static char * near
decode_type(int type)
{
switch(type){
case I:
return "I";
case SABM:
return "SABM";
case DISC:
return "DISC";
case DM:
return "DM";
case UA:
return "UA";
case RR:
return "RR";
case RNR:
return "RNR";
case REJ:
return "REJ";
case FRMR:
return "FRMR";
case UI:
return "UI";
default:
return "[invalid]";
}
}
/* Figure out the frame type from the control field
* This is done by masking out any sequence numbers and the
* poll/final bit after determining the general class (I/S/U) of the frame
*/
static int near
ftype(int control)
{
if((control & 1) == 0) /* An I-frame is an I-frame... */
return I;
if(control & 2) /* U-frames use all except P/F bit for type */
return (control & ~PF);
else /* S-frames use low order 4 bits for type */
return (control & 0x0f);
}
/* Dump an AX.25 packet header */
void
ax25_dump(FILE *fp,struct mbuf **bpp,int check)
{
char tmp[AXBUF], tmp1[AXBUF], frmr[3], cp[2 * AXALEN];
int control, pid, seg, ipcam, cmdrsp, type, unsegmented = 0;
struct mbuf *bp;
trprintf(fp,"AX25: ");
if(pullup(bpp,cp,2 * AXALEN) == (2 * AXALEN)) {
#ifdef DAMA_S
char dama_master = DAMA - (cp[ALEN + AXALEN] & DAMA); /* DAMA bke 920609 */
trprintf(fp,"%s %sto %s ",
pax25(tmp,&cp[AXALEN]),
dama_master ? "[DAMA] " : "",
pax25(tmp1,cp));
#else
trprintf(fp,"%s to %s ",
pax25(tmp,&cp[AXALEN]),
pax25(tmp1,cp));
#endif
if(((cp[ALEN]) & C) == (cp[ALEN + AXALEN] & C)) {
cmdrsp = VERS1;
} else {
cmdrsp = (cp[ALEN] & C) ? DST_C : SRC_C;
}
if((cp[ALEN + AXALEN] & E) == 0) {
trprintf(fp,"via ");
while((cp[ALEN] & E) == 0) {
if(pullup(bpp,cp,AXALEN) == AXALEN)
trprintf(fp,"%s%s ",pax25(tmp,cp),(cp[ALEN] & REPEATED) ? "*" : "");
else
goto err;
}
}
} else {
goto err;
}
if((control = PULLCHAR(bpp)) == -1) {
err:
trprintf(fp,"bad header\n");
return;
}
trprintf(fp,"%s",decode_type((type = ftype(control))));
if(control & PF) {
switch(cmdrsp) {
case CMD:
trprintf(fp,"(P)");
break;
case RESP:
trprintf(fp,"(F)");
break;
default:
trprintf(fp,"(P/F)");
break;
}
}
/* Dump sequence numbers */
if((type & 0x3) != U) /* I or S frame? */
trprintf(fp," NR=%d",(control>>5)&7);
if(type == I || type == UI) {
if(type == I) {
trprintf(fp," NS=%d",(control>>1)&7);
}
/* Decode I field */
if((pid = PULLCHAR(bpp)) != -1){ /* Get pid */
if(pid == PID_SEGMENT){
seg = PULLCHAR(bpp);
trprintf(fp,"%s remain %u",seg & SEG_FIRST ?
" First seg;" : "",seg & SEG_REM);
if(seg & SEG_FIRST)
pid = PULLCHAR(bpp);
} else
unsegmented = 1;
/* IPCAM-feature - DB3FL.910104 */
bp = *bpp;
if(pid == PID_NO_L3 && bp->cnt >= 20
&& bp->data[0] == 0x45
&& bp->data[1] == 0x00
&& bp->data[2] < 0x02) {
pid = PID_IP;
ipcam = 1;
}
else
ipcam=0;
/* */
if(pid == PID_SEGMENT) {
trprintf(fp,"\n");
} else {
trprintf(fp," pid=");
switch(pid){
case PID_ARP:
trprintf(fp,"ARP\n");
arp_dump(fp,bpp);
break;
case PID_NETROM:
trprintf(fp,"NET/ROM\n");
#ifdef NETROM
/* Don't verify checksums unless unsegmented */
netrom_dump(fp,bpp,unsegmented);
#endif
break;
case PID_IP:
if(ipcam)
trprintf(fp,"IPCAM\n");
else
trprintf(fp,"IP\n");
/* Don't verify checksums unless unsegmented */
ip_dump(fp,bpp,unsegmented);
break;
case PID_X25:
trprintf(fp,"X.25\n");
break;
case PID_TEXNET:
trprintf(fp,"TEXNET\n");
break;
case PID_FLEXNET:
trprintf(fp,"FLEXNET\n");
#ifdef FLEXNET
flexnet_dump(fp,bpp); /* to be written */
#endif
break;
case PID_NO_L3:
trprintf(fp,"Text\n");
break;
default:
trprintf(fp,"0x%x\n",pid);
}
}
}
} else if(type == FRMR && pullup(bpp,frmr,3) == 3){
trprintf(fp," Vr=%d Vs=%d",
(frmr[1] >> 5) & MMASK,(frmr[1] >> 1) & MMASK);
if(frmr[2] & W)
trprintf(fp," Invalid control field");
if(frmr[2] & X)
trprintf(fp," Illegal I-field");
if(frmr[2] & Y)
trprintf(fp," Too-long I-field");
if(frmr[2] & Z)
trprintf(fp," Invalid seq number");
trprintf(fp,": %s\n",decode_type(ftype(frmr[0])));
} else {
trprintf(fp,"\n");
}
}
/* Return 1 if this packet is directed to us, 0 otherwise. Note that
* this checks only the ultimate destination, not the digipeater field
*/
int
ax_forus(struct iface *iface,struct mbuf *bp)
{
return (addreq(bp->data,iface->hwaddr));
}
#endif /* AX25 */